package club.dingzm.myapplication;

import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import androidx.core.app.ActivityCompat;

import com.alibaba.fastjson.JSONObject;
import com.lzy.okgo.OkGo;
import com.lzy.okgo.cache.CacheMode;
import com.lzy.okgo.cookie.CookieJarImpl;
import com.lzy.okgo.cookie.store.MemoryCookieStore;
import com.lzy.okgo.https.HttpsUtils;
import com.lzy.okgo.interceptor.HttpLoggingInterceptor;
import com.lzy.okgo.model.HttpHeaders;
import com.lzy.okgo.model.HttpParams;
import com.yanzhenjie.permission.runtime.Permission;

import java.math.BigDecimal;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;

import club.dingzm.myapplication.HttpBreakPoint.BreakpointInfo;
import club.dingzm.myapplication.HttpBreakPoint.HttpBreakpointUtil;
import okhttp3.OkHttpClient;

/**
 * 使用http 的文件分片方式进行上传文件
 *  使用工具类是：HttpBreakpointUtil
 */
public class HttpDemoActivity extends Activity {

    // 需要用到的各个控件对象
    private Button btnConnectDevice = null;
    private Button print = null;
    private TextView tv_progress = null;

    private Timer timer ;
    private String cacheId = "";
    private String filePath = "";
    private HttpBreakpointUtil httpBreakpointUtil = new HttpBreakpointUtil();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.http_demo);
        //授权 允许读写权限
        String[] PERMISSIONS_STORAGE = {
                Permission.READ_EXTERNAL_STORAGE,
                Permission.WRITE_EXTERNAL_STORAGE,"android.permission.INSTALL_PACKAGES" };
        int permission = ActivityCompat.checkSelfPermission(HttpDemoActivity.this,"android.permission.INSTALL_PACKAGES");
        if (permission != PackageManager.PERMISSION_GRANTED) {
            // 没有写的权限，去申请写的权限，会弹出对话框
            ActivityCompat.requestPermissions(HttpDemoActivity.this,PERMISSIONS_STORAGE,3);
        }

        initOkGo();
        btnConnectDevice = (Button) findViewById(R.id.btn_printer);
        btnConnectDevice.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startSocket(v);
            }
        });
        //缓存Id,传入 工具类里面，每次调用成功之后，缓存当前进度
        cacheId = "id11414214214";
        filePath = "/storage/emulated/0/Download/Spring Boot+Vue.pdf";
        print=(Button)findViewById(R.id.btn_dayin);
        print.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                stopSocket(v);
            }
        });
        tv_progress= findViewById(R.id.tv_progress);
    }

    // 选择开始传输数据
    public void startSocket(View view) {
        if ( SPUtil.contains(this, cacheId) ) {
            String id = (String) SPUtil.get(getApplicationContext(), cacheId, "");
            BreakpointInfo info = JSONObject.parseObject(id,BreakpointInfo.class);
            //如果 缓存数据为空 则重新上传 文件
            if ( id == null || id == "" || info == null){
                httpBreakpointUtil.initSendFile(getApplicationContext(),filePath ,cacheId);
            }else{
                info.setFilePath(info.getFilePath());
                httpBreakpointUtil.initSendFile(getApplicationContext(),info,cacheId);
            }
        }else{
            httpBreakpointUtil.initSendFile(getApplicationContext(),filePath ,cacheId);
        }
        timer = new Timer();
        timer.schedule(new TimerTask() {
            public void run() {
                BreakpointInfo info = httpBreakpointUtil.getInfo();
                System.out.println("文件大小："+info.getFileLength());
                System.out.println("文件已上传大小："+ info.getCurrentBlock() * BreakpointInfo.CHUNK_SIZE );
                BigDecimal bg = new BigDecimal(0);
                if ( info.getFileLength() != 0){
                    bg = new BigDecimal( info.getCurrentBlock() * 100.0 / info.getBLOCK_SIZE());
                }
                double f1 = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                System.out.println(""+f1+"%");
                tv_progress.setText( ""+f1+"%" );
                if (httpBreakpointUtil.getStopFlag()){
                    timer.cancel();
                }
            }
        }, 0 , 5000);

    }

    /**
     * 选择 停止传输数据
     * @param view
     */
    public void stopSocket(View view) {
        timer.cancel();
        httpBreakpointUtil.setStop(true);
        timer = new Timer();
        //这个任务执行一次
        timer.schedule(new TimerTask() {
            public void run() {
                BreakpointInfo info = httpBreakpointUtil.getInfo();
                System.out.println("文件大小："+info.getFileLength());
                System.out.println("文件已上传大小："+ info.getCurrentBlock() * BreakpointInfo.CHUNK_SIZE );

                //获取最终的进度情况
                BigDecimal bg = new BigDecimal(0);
                if ( info.getFileLength() != 0){
                    bg = new BigDecimal( info.getCurrentBlock() * 100.0 / info.getBLOCK_SIZE());
                }
                double f1 = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                tv_progress.setText( ""+f1+"%" );
                String infoStr = JSONObject.toJSONString(info);
                System.out.println("当前已上传文件信息："+infoStr);
//                SPUtil.put(getApplicationContext(), cacheId, infoStr);
                if (httpBreakpointUtil.getStopFlag()){
                    timer.cancel();
                }
            }
        }, 1000 );

    }

    @Override
    protected void onDestroy() {
        System.out.println("进入onDestroy");
        timer.cancel();
        httpBreakpointUtil.setStop(true);
        //获取最终的进度情况
        BreakpointInfo info = httpBreakpointUtil.getInfo();

        String infoStr = JSONObject.toJSONString(info);
        SPUtil.put(getApplicationContext(), cacheId, infoStr);
        System.out.println("当前已上传文件信息："+infoStr);
        System.out.println("销毁前写入缓存");
        super.onDestroy();
    }

    private void initOkGo() {
        //---------这里给出的是示例代码,告诉你可以这么传,实际使用的时候,根据需要传,不需要就不传-------------//
        HttpHeaders headers = new HttpHeaders();
        headers.put("user", "1BE985110EBCFF2E8E3EE8D6DA94D426");    //header不支持中文，不允许有特殊字符
        //headers.put("commonHeaderKey2", "commonHeaderValue2");
        HttpParams params = new HttpParams();
        //params.put("commonParamsKey1", "commonParamsValue1");     //param支持中文,直接传,不要自己编码
        //params.put("commonParamsKey2", "这里支持中文参数");
        // params.put("AndroidVersion",localVersion);
        //params.put("AndroidId",AndroidId);
        //----------------------------------------------------------------------------------------//

        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        //log相关
        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor("OkGo");
        loggingInterceptor.setPrintLevel(HttpLoggingInterceptor.Level.BODY);        //log打印级别，决定了log显示的详细程度
        loggingInterceptor.setColorLevel(Level.INFO);                               //log颜色级别，决定了log在控制台显示的颜色
        builder.addInterceptor(loggingInterceptor);                                 //添加OkGo默认debug日志
        //第三方的开源库，使用通知显示当前请求的log，不过在做文件下载的时候，这个库好像有问题，对文件判断不准确
        //builder.addInterceptor(new ChuckInterceptor(this));

        //超时时间设置，默认60秒
//        builder.readTimeout(OkGo.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);      //全局的读取超时时间
//        builder.writeTimeout(OkGo.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);     //全局的写入超时时间
//        builder.connectTimeout(OkGo.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);   //全局的连接超时时间
        builder.readTimeout(30000, TimeUnit.MILLISECONDS);      //全局的读取超时时间
        builder.writeTimeout(30000, TimeUnit.MILLISECONDS);     //全局的写入超时时间
        builder.connectTimeout(30000, TimeUnit.MILLISECONDS);   //全局的连接超时时间

        //自动管理cookie（或者叫session的保持），以下几种任选其一就行
        //builder.cookieJar(new CookieJarImpl(new SPCookieStore(this)));            //使用sp保持cookie，如果cookie不过期，则一直有效
        //builder.cookieJar(new CookieJarImpl(new DBCookieStore(this)));              //使用数据库保持cookie，如果cookie不过期，则一直有效
        builder.cookieJar(new CookieJarImpl(new MemoryCookieStore()));            //使用内存保持cookie，app退出后，cookie消失

        //https相关设置，以下几种方案根据需要自己设置
        //方法一：信任所有证书,不安全有风险
        HttpsUtils.SSLParams sslParams1 = HttpsUtils.getSslSocketFactory();
        //方法二：自定义信任规则，校验服务端证书
        //HttpsUtils.SSLParams sslParams2 = HttpsUtils.getSslSocketFactory(new SafeTrustManager());
        //方法三：使用预埋证书，校验服务端证书（自签名证书）
        //HttpsUtils.SSLParams sslParams3 = HttpsUtils.getSslSocketFactory(getAssets().open("srca.cer"));
        //方法四：使用bks证书和密码管理客户端证书（双向认证），使用预埋证书，校验服务端证书（自签名证书）
        //HttpsUtils.SSLParams sslParams4 = HttpsUtils.getSslSocketFactory(getAssets().open("xxx.bks"), "123456", getAssets().open("yyy.cer"));
        builder.sslSocketFactory(sslParams1.sSLSocketFactory, sslParams1.trustManager);
        //配置https的域名匹配规则，详细看demo的初始化介绍，不需要就不要加入，使用不当会导致https握手失败
        //builder.hostnameVerifier(new SafeHostnameVerifier());

        // 其他统一的配置
        // 详细说明看GitHub文档：https://github.com/jeasonlzy/
        OkGo.getInstance().init(this.getApplication())                           //必须调用初始化
                .setOkHttpClient(builder.build())               //建议设置OkHttpClient，不设置会使用默认的
                .setCacheMode(CacheMode.NO_CACHE)               //全局统一缓存模式，默认不使用缓存，可以不传
                //.setCacheTime(CacheEntity.CACHE_NEVER_EXPIRE)   //全局统一缓存时间，默认永不过期，可以不传
                // .setCacheTime(600000)   //全局统一缓存时间，默认永不过期，可以不传
                .setRetryCount(0)                               //全局统一超时重连次数，默认为三次，那么最差的情况会请求4次(一次原始请求，三次重连请求)，不需要可以设置为0
                .addCommonHeaders(headers)                      //全局公共头
                .addCommonParams(params);                      //全局公共参数
    }
    
}